
interface IOption {
	routes: any[]
	platform: string
}
interface IPage {
	path?: string
	name?: string
	params?: any
}

export class Router {
	routes: any[]
	platform: string
	
	constructor(options:IOption) {
		this.routes = options.routes
		this.platform = options.platform
	}
	
	
	
	push(page:string|IPage):Promise<any> {
		return new Promise((resolve, reject) => {
			if (typeof page === "string") {
				uni.navigateTo({ url: page, complete(res:any) { resolve(res) } })
			} else if (typeof page === "object") {
				let push_url = ""
				if (page.path) {
					push_url = page.path
				} else if (page.name) {
					for (let i in this.routes) {
						if (this.routes[i].name === page.name) {
							push_url = this.routes[i].path
							break
						}
					}
				} else {
					reject("params error")
				}
				uni.navigateTo({ url: this.params2string(page.params, push_url), complete(res:any) { resolve(res) } })
			} else {
				reject("params error")
			}
		})
	}
	
	/**
	 * replace
	 */
	replace(page: string|IPage): Promise<any> {
		return new Promise((resolve, reject) => {
			if (typeof page === "string") {
				uni.redirectTo({ url: page, complete(res) { resolve(res) } })
			} else if (typeof page === "object") {
				let push_url = ""
				if (page.path) {
					push_url = page.path
				} else if (page.name) {
					for (let i in this.routes) {
						if (this.routes[i].name === page.name) {
							push_url = this.routes[i].path
							break
						}
					}
				} else {
					reject("params error")
				}
				uni.redirectTo({ url: this.params2string(page.params, push_url), complete(res) { resolve(res) } })
			} else {
				reject("params error")
			}
		})
	}
	
	/**
	 * replaceAll
	 */
	replaceAll(url:string|IPage) {
		return new Promise((resolve, reject) => {
			if (typeof url === "string") {
				// if (isTab(url, this.router, "path")) {
				uni.reLaunch({ url, complete(res) { resolve(res) } })
				// }
			} else if (typeof url === "object") {
				let push_url = ""
				if (url.path) {
					push_url = url.path
				} else if (url.name) {
					for (let i in this.routes) {
						if (this.routes[i].name === url.name) {
							push_url = this.routes[i].path
							break
						}
					}
				} else {
					reject("params error")
				}
				uni.reLaunch({ url: this.params2string(url.params, push_url), complete(res) { resolve(res) } })
			} else {
				reject("params error")
			}
		})
	}
	
	/**
	 * 回退
	 */
	back(delta: number = 1):Promise<any> {
		return new Promise((resolve, reject) => {
			uni.navigateBack({
				delta,
				success: (res) => {
					resolve(res)
				},
				fail: (err) => {
					reject(err)
				}
			})
		})
	}

	/**
	 * 是否为Tab页
	 * @param el 
	 * @param arr 
	 * @param key 
	 * @returns 
	 */
	private isTab(el:string, arr:any[], key = "name") {
		for (let i in arr) {
			if (arr[i][key] === el)
				return arr[i].meta !== undefined && arr[i].meta.tabBar
		}
	}

	/**
	 * 对象参数转化为路径参数
	 * @param {Object} obj 对象数据
	 * @param {String} url 原始路径
	 * @param {Boolean} isEncode 是否编译原参数
	 */
	private params2string(obj:any, url:string = "", isEncode:boolean = false):string {
		if (!obj || JSON.stringify(obj) === '{}') return url ? url : ""
		url += url ? "?" : ""
		
		if (isEncode) {
			for (let i in obj) {
				url += i + "=" + encodeURIComponent(obj[i]) + "&"
			}
		} else {
			for (let i in obj) {
				url += i + "=" + obj[i] + "&"
			}
		}
		url = url.substring(0, url.length - 1)
		return url
	}
}